package com.onenine.app.activity;

import android.annotation.TargetApi;
import android.content.Intent;
import android.media.AudioManager;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.SurfaceView;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.onenine.app.R;
import com.onenine.app.utils.CHelper;
import com.onenine.app.utils.GlideUtils;
import com.onenine.base.okhttp.OkRequest;
import com.onenine.base.utils.Toasty;
import com.onenine.chat.model.LUser;
import com.onenine.chat.rongcloud.PermissionCheckUtil;
import com.onenine.chat.rongcloud.RcImMgr;
import com.onenine.chat.rongcloud.RongCallAction;
import com.onenine.chat.rongcloud.UserCacheMgr;
import com.onenine.common.util.ApUtils;

import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Set;

import io.rong.calllib.CallUserProfile;
import io.rong.calllib.RongCallClient;
import io.rong.calllib.RongCallCommon;
import io.rong.calllib.RongCallSession;
import io.rong.calllib.message.MultiCallEndMessage;
import io.rong.common.RLog;
import io.rong.imlib.RongIMClient;
import io.rong.imlib.model.Conversation;
import io.rong.imlib.model.Message;
import io.rong.imlib.model.UserInfo;
import io.rong.message.GroupNotificationMessage;

/**
 * 允许偷听的多方语音
 */
public class MultiAudioCallActivity extends BaseCallActivity {
    private static final String TAG = "VoIPMultiAudioCallActivity";
    private LinearLayout audioContainer;

    private RelativeLayout incomingLayout;
    private RelativeLayout outgoingLayout;
    private FrameLayout outgoingController;
    private FrameLayout incomingController;
    private RongCallAction callAction;
    private RongCallSession callSession;

    private boolean shouldShowFloat = true;
    private boolean startForCheckPermissions = false;
    private boolean handFree = false;
    private boolean isEaving = false;
    private boolean isMinimize = false;
    private String mTargetId, mPkId;
    private ArrayList<String> mInvitedList;
    private Set<String> mEavUsers = new HashSet<>();

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (savedInstanceState != null && RongCallClient.getInstance() == null) {
            // 音视频请求权限时，用户在设置页面取消权限，导致应用重启，退出当前activity.
            finish();
            return;
        }
        mTargetId = getIntent().getStringExtra("targetId");
        mPkId = getIntent().getStringExtra("pkId");
        mInvitedList = getIntent().getStringArrayListExtra("invitedUsers");
        audioContainer = findViewById(R.id.rc_voip_container);
        incomingLayout = (RelativeLayout) LayoutInflater.from(this).inflate(R.layout.rc_voip_item_incoming_maudio, null);
        outgoingLayout = (RelativeLayout) LayoutInflater.from(this).inflate(R.layout.rc_voip_item_outgoing_maudio, null);
        outgoingController = (FrameLayout) LayoutInflater.from(this).inflate(R.layout.rc_voip_voice_call_bottom_button_layout, null);
        incomingController = (FrameLayout) LayoutInflater.from(this).inflate(R.layout.rc_voip_call_bottom_incoming_button_layout, null);
        startForCheckPermissions = getIntent().getBooleanExtra("checkPermissions", false);
        if (requestCallPermissions(RongCallCommon.CallMediaType.AUDIO, REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS)) {
            initView();
        }
    }

    @Override
    protected void setStatusBarStyle() {
    }

    @Override
    protected int getLayout() {
        return R.layout.rc_voip_ac_muti_audio;
    }

    @Override
    protected void onNewIntent(Intent intent) {
        startForCheckPermissions = getIntent().getBooleanExtra("checkPermissions", false);
        super.onNewIntent(intent);
        if (requestCallPermissions(RongCallCommon.CallMediaType.AUDIO, REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS)) {
            initView();
        }
    }

    @TargetApi(23)
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS:
                if (PermissionCheckUtil.checkPermissions(this, AUDIO_CALL_PERMISSIONS)) {
                    if (startForCheckPermissions) {
                        startForCheckPermissions = false;
                        RongCallClient.getInstance().onPermissionGranted();
                    } else {
                        initView();
                    }
                } else {
                    if (startForCheckPermissions) {
                        startForCheckPermissions = false;
                        Toasty.showNormal(R.string.rc_permission_grant_needed);
                        RongCallClient.getInstance().onPermissionDenied();
                    } else {
                        finish();
                    }
                }
                break;

            default:
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

    @Override
    public void onRestoreFloatBox(Bundle bundle) {
        super.onRestoreFloatBox(bundle);
        isMinimize = false;
        if (bundle != null) {
            handFree = bundle.getBoolean("handFree");
            audioContainer.addView(outgoingLayout);
            FrameLayout controller = audioContainer.findViewById(R.id.rc_voip_control_layout);
            controller.addView(outgoingController);
            callSession = RongCallClient.getInstance().getCallSession();

            if (callSession == null) {
                setShouldShowFloat(false);
                finish();
                return;
            }
            mTargetId = callSession.getTargetId();
            mPkId = bundle.getString("pkId");
            isEaving = bundle.getBoolean("isEaving");
            String[] eavUsers = bundle.getStringArray("eavUsers");
            for (String str : eavUsers) {
                mEavUsers.add(str);
            }
            onCallConnected(callSession, null);
        }
    }

    void initView() {
        Intent intent = getIntent();
        callAction = RongCallAction.valueOf(intent.getStringExtra("callAction"));
        if (callAction == null || callAction.equals(RongCallAction.ACTION_RESUME_CALL)) {
            return;
        }
        if (callAction.equals(RongCallAction.ACTION_INCOMING_CALL)) {
            callSession = intent.getParcelableExtra("callSession");
            mTargetId = callSession.getTargetId();
            if (!TextUtils.isEmpty(callSession.getExtra())) {
                //接收发起者传过来的pkId，用于解散偷听室
                mPkId = callSession.getExtra();
            }
            final TextView name = incomingLayout.findViewById(R.id.rc_user_name);
            final ImageView userPortrait = incomingLayout.findViewById(R.id.rc_voip_user_portrait);
            UserCacheMgr.getInstance().getUserAsync(callSession.getCallerUserId(), new UserCacheMgr.OnUserCallback() {
                @Override
                public void callback(LUser user) {
                    name.setText(user.getNickName());
                    GlideUtils.loadSrcImage(ApUtils.getApp(), userPortrait, CHelper.getOssThumbImageUrl(user.getPhoto()
                            , getResources().getDimensionPixelOffset(R.dimen.pic_size_100dp)));
                    name.setTag(callSession.getCallerUserId() + "callerName");
                }
            });
            audioContainer.addView(incomingLayout);
            FrameLayout controller = audioContainer.findViewById(R.id.rc_voip_control_layout);
            controller.addView(incomingController);
            onIncomingCallRinging();
        } else if (callAction.equals(RongCallAction.ACTION_OUTGOING_CALL)) {
            Conversation.ConversationType conversationType = Conversation.ConversationType.valueOf(intent.getStringExtra("conversationType").toUpperCase(Locale.US));
            audioContainer.addView(outgoingLayout);
            FrameLayout controller = audioContainer.findViewById(R.id.rc_voip_control_layout);
            controller.addView(outgoingController);
            if (mInvitedList != null && !mInvitedList.isEmpty()) {
                final ImageView ivAvatar = outgoingLayout.findViewById(R.id.ic_avatar);
                final TextView tvName = outgoingLayout.findViewById(R.id.tv_name);
                UserCacheMgr.getInstance().getUserAsync(mInvitedList.get(0), new UserCacheMgr.OnUserCallback() {
                    @Override
                    public void callback(LUser user) {
                        GlideUtils.loadSrcImage(ApUtils.getApp(), ivAvatar
                                , CHelper.getOssThumbImageUrl(user.getPhoto()
                                        , getResources().getDimensionPixelOffset(R.dimen.pic_size_100dp)));
                        tvName.setText(user.getNickName());
                    }
                });
            }
            RongCallClient.getInstance().startCall(conversationType, mTargetId
                    , mInvitedList, null, RongCallCommon.CallMediaType.AUDIO, mPkId);
        }
        createPowerManager();
        createPickupDetector();
    }

    @Override
    protected void onPause() {
        if (pickupDetector != null) {
            pickupDetector.unRegister();
        }
        super.onPause();
    }

    @Override
    protected void onResume() {
        if (pickupDetector == null) createPickupDetector();
        if (wakeLock == null) createPowerManager();
        if (pickupDetector != null) {
            pickupDetector.register(this);
        }
        super.onResume();
    }


    public void onHangupBtnClick(View view) {
        if (callSession == null || isFinishing) {
            return;
        }
        RongCallClient.getInstance().hangUpCall(callSession.getCallId());
    }

    public void onReceiveBtnClick(View view) {
        if (callSession == null || isFinishing) {
            return;
        }
        RongCallClient.getInstance().acceptCall(callSession.getCallId());

    }

    @Override
    protected void onAddMember(List<String> newMemberIds) {
        if (newMemberIds == null || newMemberIds.isEmpty()) {
            return;
        }
        ArrayList<String> added = new ArrayList<>();
        ArrayList<String> participants = new ArrayList<>();
        List<CallUserProfile> list = RongCallClient.getInstance().getCallSession().getParticipantProfileList();
        for (CallUserProfile profile : list) {
            participants.add(profile.getUserId());
        }
        for (String id : newMemberIds) {
            if (participants.contains(id)) {
                continue;
            } else {
                added.add(id);
            }
        }
        if (added.isEmpty()) {
            return;
        }
        RongCallClient.getInstance().addParticipants(callSession.getCallId(), mInvitedList, added);
    }

    @Override
    public void onRemoteUserRinging(String userId) {

    }

    @Override
    public void onCallOutgoing(RongCallSession callSession, SurfaceView localVideo) {
        super.onCallOutgoing(callSession, localVideo);
        this.callSession = callSession;
        onOutgoingCallRinging();
    }

    @Override
    public void onRemoteUserInvited(String userId, RongCallCommon.CallMediaType mediaType) {
        super.onRemoteUserInvited(userId, mediaType);
    }

    @Override
    public void onRemoteUserJoined(String userId, RongCallCommon.CallMediaType mediaType, int userType, SurfaceView remoteVideo) {
    }

    @Override
    public void onRemoteUserLeft(final String userId, RongCallCommon.CallDisconnectedReason reason) {
        super.onRemoteUserLeft(userId, reason);
    }

    @Override
    public void onNetworkReceiveLost(int i) {

    }

    @Override
    public void onNetworkSendLost(int i) {

    }

    @Override
    public void onNotifyAnswerUpgradeObserverToNormalUser(String s, SurfaceView surfaceView) {

    }

    @Override
    public void onCallConnected(final RongCallSession callSession, SurfaceView localVideo) {
        super.onCallConnected(callSession, localVideo);
        RongCallClient.getInstance().setEnableLocalVideo(false);
        this.callSession = callSession;
        AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
        if (audioManager.isWiredHeadsetOn()) {
            RongCallClient.getInstance().setEnableSpeakerphone(false);
        } else {
            RongCallClient.getInstance().setEnableSpeakerphone(handFree);
        }
        stopRing();

        if (callAction.equals(RongCallAction.ACTION_INCOMING_CALL)) {
            audioContainer.removeAllViews();
            FrameLayout controller = outgoingLayout.findViewById(R.id.rc_voip_control_layout);
            controller.addView(outgoingController);
            audioContainer.addView(outgoingLayout);
            final TextView name = outgoingLayout.findViewById(R.id.tv_name);
            final ImageView userPortrait = outgoingLayout.findViewById(R.id.ic_avatar);
            UserCacheMgr.getInstance().getUserAsync(callSession.getCallerUserId(), new UserCacheMgr.OnUserCallback() {
                @Override
                public void callback(LUser user) {
                    name.setText(user.getNickName());
                    GlideUtils.loadSrcImage(ApUtils.getApp(), userPortrait
                            , CHelper.getOssThumbImageUrl(user.getPhoto()
                                    , getResources().getDimensionPixelOffset(R.dimen.pic_size_100dp)));
                }
            });
        } else if (callAction.equals(RongCallAction.ACTION_OUTGOING_CALL)) {
            View handFreeV = audioContainer.findViewById(R.id.rc_voip_call_mute);
            View handFreeBtn = outgoingLayout.findViewById(R.id.rc_voip_handfree_btn);
            handFreeV.setVisibility(View.VISIBLE);
            handFreeBtn.setSelected(handFree);
        } else if (callAction.equals(RongCallAction.ACTION_RESUME_CALL)) {
            final TextView name = outgoingLayout.findViewById(R.id.tv_name);
            final ImageView userPortrait = outgoingLayout.findViewById(R.id.ic_avatar);
            UserCacheMgr.getInstance().getUserAsync(callSession.getCallerUserId(), new UserCacheMgr.OnUserCallback() {
                @Override
                public void callback(LUser user) {
                    name.setText(user.getNickName());
                    GlideUtils.loadSrcImage(ApUtils.getApp(), userPortrait
                            , CHelper.getOssThumbImageUrl(user.getPhoto()
                                    , getResources().getDimensionPixelOffset(R.dimen.pic_size_100dp)));
                }
            });
        }
        outgoingLayout.findViewById(R.id.rc_voip_handfree_btn).setVisibility(View.VISIBLE);
        outgoingLayout.findViewById(R.id.rc_voip_call_mute).setVisibility(View.VISIBLE);

        View handFreeV = outgoingLayout.findViewById(R.id.rc_voip_handfree_btn);
        handFreeV.setVisibility(View.VISIBLE);
        handFreeV.setSelected(handFree);

        TextView timeV = outgoingLayout.findViewById(R.id.rc_voip_remind);
        setupTime(timeV);

        View minimizeV = outgoingLayout.findViewById(R.id.rc_voip_minimize);
        minimizeV.setVisibility(View.VISIBLE);
        minimizeV.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                MultiAudioCallActivity.super.onMinimizeClick(v);
            }
        });
    }


    @Override
    public void onCallDisconnected(RongCallSession callSession, RongCallCommon.CallDisconnectedReason reason) {
        super.onCallDisconnected(callSession, reason);

        isFinishing = true;
        if (reason == null || callSession == null) {
            RLog.e(TAG, "onCallDisconnected. callSession is null!");
            postRunnableDelay(new Runnable() {
                @Override
                public void run() {
                    finish();
                }
            });
            return;
        }

        MultiCallEndMessage multiCallEndMessage = new MultiCallEndMessage();
        multiCallEndMessage.setReason(reason);
        multiCallEndMessage.setMediaType(RongIMClient.MediaType.AUDIO);
        if (reason != null) {
            RongIMClient.getInstance().insertMessage(callSession.getConversationType()
                    , callSession.getTargetId(), callSession.getCallerUserId(), multiCallEndMessage, null);
        }
        stopRing();
        postRunnableDelay(new Runnable() {
            @Override
            public void run() {
                finish();
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS) {
            if (PermissionCheckUtil.checkPermissions(this, AUDIO_CALL_PERMISSIONS)) {
                if (startForCheckPermissions) {
                    startForCheckPermissions = false;
                    RongCallClient.getInstance().onPermissionGranted();
                } else {
                    initView();
                }
            } else {
                if (startForCheckPermissions) {
                    startForCheckPermissions = false;
                    RongCallClient.getInstance().onPermissionDenied();
                } else {
                    finish();
                }
            }

        } else if (requestCode == REQUEST_CODE_ADD_MEMBER) {
            if (callSession.getEndTime() != 0) {
                finish();
                return;
            }
            shouldShowFloat = true;
            if (resultCode == RESULT_OK) {
                ArrayList<String> invited = data.getStringArrayListExtra("invited");
                RongCallClient.getInstance().addParticipants(callSession.getCallId(), invited, null);
            }
        }
    }

    /**
     * 通知偷听室已解散，成员退出
     */
    private void quitEavesDropChatRoom() {
        RcImMgr.getInstance().sendGroupDismissMessage(mTargetId, new RcImMgr.OnMessageListener() {
            @Override
            public void onSuccess(Message message) {
            }

            @Override
            public void onProgress(Message message) {

            }

            @Override
            public void onFailure(RongIMClient.ErrorCode errorCode) {

            }
        });
    }

    public void onHandFreeButtonClick(View view) {
        RongCallClient.getInstance().setEnableSpeakerphone(!view.isSelected());
        view.setSelected(!view.isSelected());
        handFree = view.isSelected();
    }

    public void onMuteButtonClick(View view) {
        RongCallClient.getInstance().setEnableLocalAudio(view.isSelected());
        view.setSelected(!view.isSelected());
    }

    @Override
    public String onSaveFloatBoxState(Bundle bundle) {
        super.onSaveFloatBoxState(bundle);
        isMinimize = true;
        String intentAction = null;
        if (shouldShowFloat) {
            intentAction = getIntent().getAction();
            bundle.putInt("mediaType", RongCallCommon.CallMediaType.AUDIO.getValue());
            bundle.putString("pkId", mPkId);
            bundle.putBoolean("handFree", handFree);
            bundle.putBoolean("isEaving", isEaving);
            bundle.putStringArray("eavUsers", mEavUsers.toArray(new String[]{}));
        }
        return intentAction;
    }

    @Override
    public void onBackPressed() {
        if (callSession == null) {
            callSession = RongCallClient.getInstance().getCallSession();
            if (callSession == null) {
                super.onBackPressed();
                return;
            }
        }
        List<CallUserProfile> participantProfiles = callSession.getParticipantProfileList();
        RongCallCommon.CallStatus callStatus = null;
        for (CallUserProfile item : participantProfiles) {
            if (item.getUserId().equals(callSession.getSelfUserId())) {
                callStatus = item.getCallStatus();
                break;
            }
        }
        if (callStatus != null && callStatus.equals(RongCallCommon.CallStatus.CONNECTED)) {
            super.onBackPressed();
        } else {
            RongCallClient.getInstance().hangUpCall(callSession.getCallId());
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEvent(UserInfo userInfo) {
        if (isFinishing()) {
            return;
        }
        TextView callerName = audioContainer.findViewWithTag(userInfo.getUserId() + "callerName");
        if (callerName != null && userInfo.getName() != null)
            callerName.setText(userInfo.getName());
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEvent(GroupNotificationMessage message) {
        if (message != null) {
            if (TextUtils.equals(message
                    .getOperation(), GroupNotificationMessage.GROUP_OPERATION_DISMISS)) {
                //群解散
                if (callSession != null) {
                    RongCallClient.getInstance().hangUpCall(callSession.getCallId());
                }
                shouldShowFloat = false;
                finish();
            }
        }
    }

    @Override
    public void onDestroy() {
        if (wakeLock != null && wakeLock.isHeld()) {
            wakeLock.setReferenceCounted(false);
            wakeLock.release();
        }
        if (isEaving && !isMinimize && !TextUtils.isEmpty(mTargetId) && !TextUtils.isEmpty(mPkId)) {
            quitEavesDropChatRoom();
        }
        mEavUsers.clear();
        OkRequest.getInstance().cancelTag(MultiAudioCallActivity.class.getSimpleName());
        super.onDestroy();
    }

}
